package com.henan.provideservice.controller;

import com.henan.provideservice.api.request.DeveloperRequest;
import com.henan.provideservice.api.response.DeveloperResponse;
import com.henan.provideservice.api.response.SsePageResponse;
import com.henan.provideservice.api.response.TestResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.time.Duration;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RestController
@RequestMapping("/develop")
@CrossOrigin(origins = "*") // 允许所有跨域请求
@Slf4j
public class DevelopController {

    @GetMapping("/list")
    public Page<DeveloperResponse> getList(DeveloperRequest request, @RequestParam(defaultValue = "1") int page,
                                          @RequestParam(defaultValue = "10") int size) {
        // 生成模拟数据（假设有100条记录）
        List<DeveloperResponse> allItems = IntStream.rangeClosed(1, 145)
                .mapToObj(i -> {
                    int randomNum = ThreadLocalRandom.current().nextInt(1, 100); // 生成随机数
                    DeveloperResponse.Sex sex = (randomNum % 2 == 1) ? DeveloperResponse.Sex.FEMALE : DeveloperResponse.Sex.MALE;
                    return new DeveloperResponse(i, "name" + i, i + 10, sex, "role" + i, 10000 + i);
                })
                .collect(Collectors.toList());

        // 创建分页对象
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("id").ascending());

        // 计算分页索引
        int fromIndex = (int) pageable.getOffset();
        int toIndex = Math.min(fromIndex + pageable.getPageSize(), allItems.size());

        // 获取分页数据
        List<DeveloperResponse> pageItems = (fromIndex < allItems.size()) ? allItems.subList(fromIndex, toIndex) : List.of();

        // 返回分页数据
        return new PageImpl<>(pageItems, pageable, allItems.size());
    }


    @GetMapping(value = "/sse-list-one-by-one1", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<SsePageResponse<DeveloperResponse>> streamDeveloperListOneByOne1(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        int totalRecords = 10045;
        int totalPages = (int) Math.ceil((double) totalRecords / size);
        int fromIndex = (page - 1) * size;
        int toIndex = Math.min(fromIndex + size, totalRecords);

        // 获取完整的一页数据
        List<DeveloperResponse> fullPageData = fetchDeveloperData(fromIndex, toIndex);

        return Flux.fromIterable(fullPageData)
                .map(record -> new SsePageResponse<>(Collections.singletonList(record), page, totalPages, totalRecords, size))
                .doOnCancel(() -> log.info("SSE Developer list 连接已取消"))
                .doFinally(signalType -> log.info("SSE Developer list 连接关闭: {}", signalType));
    }

    @GetMapping(value = "/sse-list-one-by-one2", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<DeveloperResponse> streamDeveloperListOneByOne2(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        int totalRecords = 10045;
        int fromIndex = (page - 1) * size;
        int toIndex = Math.min(fromIndex + size, totalRecords);

        // 获取完整的一页数据
        List<DeveloperResponse> fullPageData = fetchDeveloperData(fromIndex, toIndex);

        return Flux.fromIterable(fullPageData)
                .doOnCancel(() -> log.info("SSE Developer list 连接已取消"))
                .doFinally(signalType -> log.info("SSE Developer list 连接关闭: {}", signalType));
    }







    @GetMapping(value = "/sse-list", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<SsePageResponse<DeveloperResponse>> streamDeveloperList(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        int totalRecords = 10045;
        int totalPages = (int) Math.ceil((double) totalRecords / size);
        int fromIndex = (page - 1) * size;
        int toIndex = Math.min(fromIndex + size, totalRecords);

        // 获取完整的一页数据
        List<DeveloperResponse> fullPageData = fetchDeveloperData(fromIndex, toIndex);

        // 如果 size > 1000，每次推送 1000 条，否则一次性返回
        int batchSize = (size > 1000) ? 1000 : size;

        return Flux.fromIterable(splitList(fullPageData, batchSize))
                .map(batch -> new SsePageResponse<>(batch, page, totalPages, totalRecords, size))
//                .delayElements(Duration.ofSeconds(1))  // 每秒推送一批
                .doOnCancel(() -> log.info("SSE Developer list 连接已取消"))
                .doFinally(signalType -> log.info("SSE Developer list 连接关闭: {}", signalType));
    }

    /**
     * 根据批次大小拆分列表
     */
    private List<List<DeveloperResponse>> splitList(List<DeveloperResponse> data, int batchSize) {
        List<List<DeveloperResponse>> batches = new ArrayList<>();
        for (int i = 0; i < data.size(); i += batchSize) {
            batches.add(data.subList(i, Math.min(i + batchSize, data.size())));
        }
        return batches;
    }

    /**
     * 模拟数据库查询
     */
    private List<DeveloperResponse> fetchDeveloperData(int fromIndex, int toIndex) {
        List<DeveloperResponse> allData = IntStream.rangeClosed(1, 10045)
                .mapToObj(
                        i -> {
                            int randomNum = ThreadLocalRandom.current().nextInt(1, 100); // 生成随机数
                            DeveloperResponse.Sex sex = (randomNum % 2 == 1) ? DeveloperResponse.Sex.FEMALE : DeveloperResponse.Sex.MALE;
                            return new DeveloperResponse(i, "name" + i, i + 10, sex, "role" + i, 10000 + i);
                        }
                )
                .collect(Collectors.toList());

        return (fromIndex < allData.size()) ? allData.subList(fromIndex, toIndex) : Collections.emptyList();
    }



}
